home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr47 / ucrasm27.zip / SOURCE.ZIP / APNDLSTM.ASM < prev    next >
Assembly Source File  |  1992-03-09  |  5KB  |  247 lines

  1.  
  2. ; Need to include "lists.a" in order to get list structure definition.
  3.  
  4.         include    lists.a
  5.         extrn    sl_malloc:far
  6.  
  7.  
  8. wp        equ    <word ptr>        ;I'm a lazy typist
  9.  
  10.  
  11. ; Special case to handle MASM 6.0 vs. all other assemblers:
  12. ; If not MASM 5.1 or MASM 6.0, set the version to 5.00:
  13.  
  14.         ifndef    @version
  15. @version    equ    500
  16.         endif
  17.  
  18.  
  19.  
  20. StdGrp        group    stdlib,stddata
  21. stddata        segment    para public 'sldata'
  22. stddata        ends
  23.  
  24. stdlib        segment    para public 'slcode'
  25.         assume    cs:stdgrp
  26.  
  27.  
  28. ; sl_AppendLastm-    DX:SI points at a block of data bytes.
  29. ;            ES:DI points at a list.
  30. ;            This routine allocates storage for a new node on the
  31. ;            heap, copies the data from DX:SI to the new node,
  32. ;            and then links in the new node to the list.
  33. ;
  34. ;            Returns the carry set if memory allocation error
  35. ;            occurs.
  36. ;
  37. ; Randall Hyde  3/3/92
  38. ;
  39.  
  40.         public    sl_AppendLastm
  41. sl_AppendLastm    proc    far
  42.         pushf
  43.         push    ds
  44.         push    cx
  45.         push    es
  46.         push    di
  47.         cld
  48.  
  49.  
  50.  
  51.         if    @version ge 600
  52.  
  53. ; MASM 6.0 version goes here
  54.  
  55.  
  56. ; First, allocate storage for the new node:
  57.  
  58.         mov    cx, es:[di].List.ListSize
  59.         push    cx            ;Save for later
  60.         add    cx, size NODE        ;Add in overhead
  61.         call    sl_malloc        ;Go get the memory
  62.         pop    cx            ;Get real length back.
  63.         jc    BadAppend        ;If malloc error
  64.         push    di            ;Save ptr to new NODE.
  65.  
  66. ; Compute offset to actual data area (skipping over list pointers, etc.)
  67.  
  68.         add    di, size Node
  69.  
  70.  
  71.         mov    ds, dx
  72.     rep    movsb                ;Copy the node's data.
  73.         pop    si            ;Get ptr to original node
  74.         mov    cx, es            ;Make ds:si point at node.
  75.         mov    ds, cx
  76.         pop    di            ;Get ptr to list var
  77.         pop    es
  78.         push    es
  79.         push    di
  80.  
  81.  
  82. ; Get the pointer to the last item in the list and store its address into the
  83. ; PREV link field of the new node:
  84.  
  85.         cmp    wp es:[di].List.Tail+2, 0    ;See if empty list
  86.         jne    ListHasNodes
  87.  
  88. ; If this is an empty list (list is empty if TAIL is NIL), then add the
  89. ; first node to the list.
  90.  
  91.         mov    wp es:[di].List.Tail, si
  92.         mov     wp es:[di].List.Head, si
  93.         mov    wp es:[di].List.CurrentNode, si
  94.  
  95.         mov    wp es:[di].List.Tail+2, dx
  96.         mov    wp es:[di].List.Head+2, dx
  97.         mov    wp es:[di].List.CurrentNode+2, dx
  98.  
  99.         mov    es, dx
  100.         mov    wp es:[si].Node.Next, 0
  101.         mov    wp es:[si].Node.Prev, 0
  102.         mov    wp es:[si].Node.Next+2, 0
  103.         mov    wp es:[si].Node.Prev+2, 0
  104.         pop    di
  105.         pop    es
  106.         jmp    GoodAppend
  107.  
  108. ;If there were items in the list, preform the append down here.
  109.  
  110. ListHasNodes:    les    di, es:[di].List.Tail        ;Get ptr to last item
  111.         mov    wp ds:[si].Node.Prev, di     ;Patch in back ptr
  112.         mov    wp ds:[si].Node.Prev+2, es
  113.  
  114. ; Okay, store the new node's address into the NEXT field of the last node
  115. ; currently in the list:
  116.  
  117.         mov    wp es:[di].Node.Next, si    ;Patch in fwd ptr
  118.         mov    wp es:[di].Node.Next+2, ds
  119.  
  120. ; Set the NEXT field of the new node to NIL:
  121.  
  122.         mov    wp ds:[si].Node.Next, 0        ;Set new node's link
  123.         mov    wp ds:[si].Node.Next+2, 0    ; to NIL.
  124.  
  125. ; Set the LAST and Current Node ptrs to the new node
  126.  
  127.         pop    di            ;Retrive ptr to list var.
  128.         pop    es
  129.         mov    wp es:[di].List.Tail, si
  130.         mov    wp es:[di].List.CurrentNode, si
  131.  
  132.         mov    wp es:[di].List.Tail+2, ds
  133.         mov    wp es:[di].List.CurrentNode+2, ds
  134.  
  135.  
  136.  
  137.  
  138.  
  139.  
  140.  
  141.  
  142.         else
  143.  
  144. ; All other assemblers come down here:
  145.  
  146. ; First, allocate storage for the new node:
  147.  
  148.         mov    cx, es:[di].ListSize
  149.         push    cx            ;Save for later
  150.         add    cx, size NODE        ;Add in overhead
  151.         call    sl_malloc        ;Go get the memory
  152.         pop    cx            ;Get real length back.
  153.         jc    BadAppend        ;If malloc error
  154.         push    di            ;Save ptr to new NODE.
  155.  
  156.         add    di, size Node         ;get ptr to data area
  157.  
  158.         mov    ds, dx
  159.     rep    movsb                ;Copy the node's data.
  160.         pop    si            ;Get ptr to original node
  161.         mov    cx, es            ;Make ds:si point at node.
  162.         mov    ds, cx
  163.         pop    di            ;Get ptr to list var
  164.         pop    es
  165.         push    es
  166.         push    di
  167.  
  168.  
  169. ; Get the pointer to the last item in the list and store its address into the
  170. ; PREV link field of the new node:
  171.  
  172.         cmp    wp es:[di].Tail+2, 0    ;See if empty list
  173.         jne    ListHasNodes
  174.  
  175. ; If this is an empty list (list is empty if TAIL is NIL), then add the
  176. ; first node to the list.
  177.  
  178.         mov    wp es:[di].Tail, si
  179.         mov     wp es:[di].Head, si
  180.         mov    wp es:[di].CurrentNode, si
  181.  
  182.         mov    wp es:[di].Tail+2, dx
  183.         mov    wp es:[di].Head+2, dx
  184.         mov    wp es:[di].CurrentNode+2, dx
  185.  
  186.         mov    es, dx
  187.         mov    wp es:[si].Next, 0
  188.         mov    wp es:[si].Prev, 0
  189.         mov    wp es:[si].Next+2, 0
  190.         mov    wp es:[si].Prev+2, 0
  191.         pop    di
  192.         pop    es
  193.         jmp    GoodAppend
  194.  
  195. ;If there were items in the list, preform the append down here.
  196.  
  197. ListHasNodes:    les    di, es:[di].Tail    ;Get ptr to last item
  198.         mov    wp ds:[si].Prev, di     ;Patch in back ptr
  199.         mov    wp ds:[si].Prev+2, es
  200.  
  201. ; Okay, store the new node's address into the NEXT field of the last node
  202. ; currently in the list:
  203.  
  204.         mov    wp es:[di].Next, si    ;Patch in fwd ptr
  205.         mov    wp es:[di].Next+2, ds
  206.  
  207. ; Set the NEXT field of the new node to NIL:
  208.  
  209.         mov    wp ds:[si].Next, 0        ;Set new node's link
  210.         mov    wp ds:[si].Next+2, 0        ; to NIL.
  211.  
  212. ; Set the LAST ptr to the new node
  213.  
  214.         pop    di            ;Retrive ptr to list var.
  215.         pop    es
  216.  
  217.         mov    wp es:[di].Tail, si
  218.         mov    wp es:[di].CurrentNode, si
  219.  
  220.         mov    wp es:[di].Tail+2, ds
  221.         mov    wp es:[di].CurrentNode+2, ds
  222.  
  223.  
  224.  
  225.         endif
  226.  
  227. ; DANGER WILL ROBINSON! Multiple exit points.  Be wary of these if you
  228. ; change the way things are pushed on the stack.
  229.  
  230. GoodAppend:    pop    cx
  231.         pop    ds
  232.         popf
  233.         clc
  234.         ret
  235.  
  236. BadAppend:    pop    di
  237.         pop    es
  238.         pop    cx
  239.         pop    ds
  240.         popf
  241.         stc
  242.         ret
  243. sl_AppendLastm    endp
  244.  
  245. stdlib        ends
  246.         end
  247.